package com.naiterui.ehp.bs.patient.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.naiterui.ehp.bp.domain.Doctor;
import com.naiterui.ehp.bp.domain.DrPhoneContact;
import com.naiterui.ehp.bp.domain.Patient;
import com.naiterui.ehp.bp.domain.PatientRecord;
import com.naiterui.ehp.bs.patient.dao.IDoctorDao;
import com.naiterui.ehp.bs.patient.dao.IDrPhoneContactDao;
import com.naiterui.ehp.bs.patient.dao.IPatientRecordDao;
import com.naiterui.ehp.bs.patient.service.IPatientRecordService;

/**
 * 患者诊疗记录业务实现
 *
 * @author Amber
 * @since 1.0.0
 */
@Service
public class ApPatientRecordServiceImpl implements IPatientRecordService {

    @Autowired
    private IPatientRecordDao patientRecordDao;
    @Autowired
    private IDrPhoneContactDao drPhoneContactDao;
    @Autowired
    private IDoctorDao doctorDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeContactsRecordByDoctor(Patient patient, Long doctorId) {
        // 患者不存在，或患者未绑定手机号或医生id为空直接返回
        if (patient == null || patient.getPhone() == null || doctorId == null) {
            return;
        }

        // 根据患者手机号获取与医生的手机联系人关系，未绑定的（没有患者id）记录
        DrPhoneContact contact = this.drPhoneContactDao.getUnBindContactByDr(patient.getPhone(), doctorId);

        // 如果存在，迁移
        if (contact != null) {
            List<DrPhoneContact> contacts = new ArrayList<>();
            List<Long> contactIds = new ArrayList<>();
            // 待迁移的手机联系人
            contacts.add(contact);
            // 手机联系人id列表
            contactIds.add(contact.getId());

            // 原手机联系人的诊疗记录
            List<PatientRecord> records = this.patientRecordDao.getContactRecords(contactIds);

            // 迁移诊疗记录，同时手机联系人标注为已关注（添加患者id）
            this.removeContactToPatient(patient.getId(), contacts, records);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePatientRecord(Patient patient) {
        // 患者不存在或手机号不存在不处理
        if (patient == null || patient.getPhone() == null) {
            return;
        }

        // 获取患者手机号相关手机联系人记录 key：医生id；value：手机联系人
        Map<Long, DrPhoneContact> drContactMap = this.drPhoneContactDao.getContactMapByPhone(patient.getPhone());

        // 获取患者私人医生数据,包括所有账户状态（禁用、非禁用的）
        List<Doctor> personalDoctors = this.doctorDao.getPersonalDoctors(patient.getId(), -1);

        // 循环私人医生数据，如果私人医生有该患者手机联系人账户且未迁移
        List<Long> contactIds = new ArrayList<>();
        List<DrPhoneContact> bindContacts = new ArrayList<>();
        for (Doctor doctor : personalDoctors) {
            DrPhoneContact contact = drContactMap.get(doctor.getId());
            // 手机联系人关联患者id为空，标识手机联系人未关联医生患者用户
            if (contact != null && contact.getPatientId() == null) {
                // 待迁移手机联系人
                bindContacts.add(contact);
                // 待迁移手机联系人id列表
                contactIds.add(contact.getId());
            }
        }

        // 获取待迁移诊疗记录
        List<PatientRecord> records = this.patientRecordDao.getContactRecords(contactIds);

        // 迁移手机联系人以及诊疗记录到患者
        this.removeContactToPatient(patient.getId(), bindContacts, records);

    }

    @Transactional(rollbackFor = Exception.class)
    private void removeContactToPatient(Long patientId, List<DrPhoneContact> contacts, List<PatientRecord> patientRecords) {
        // 患者id为空，或者
        if (patientId == null) {
            return;
        }

        if (contacts != null) {
            // 更新手机联系人为已绑定患者
            for (DrPhoneContact contact : contacts) {
                contact.setPatientId(patientId);
                // 标注手机联系人已成为医生患者
                this.drPhoneContactDao.saveOrUpdate(contact);
            }
        }

        if (patientRecords != null) {
            // 同步手机联系人诊疗记录给对应的患者账户
            for (PatientRecord record : patientRecords) {
                record.setPatientId(patientId);
                record.setType(PatientRecord.RECORD_TYPE_PATIENT);
                this.patientRecordDao.saveOrUpdate(record);
            }
        }

    }
}
